<template>
    <div class="container_box">
        <el-scrollbar class="main_box">
            <div class="content_box">
                <!-- 开发者接入流程 -->
                <div class="procedure_box">开发者接入流程</div>
                <div class="icon_box">
                    <div v-for="(item, index) in card.imageList" :key="index" class="icon_onbu">
                        <img :src="item.url" alt="" class="icon_img" />
                        <div class="steps"></div>
                        <div class="steps-name">{{ item.name }}</div>
                    </div>
                </div>
                <div class="tips">
                    开发前，请先阅读<span class="tips_text" @click="outerChain"
                        >《开发者入驻流程及API接口说明文档》</span
                    >
                </div>
                <div class="spilt"></div>

                <!-- 开发者信息 -->
                <div class="procedure_box">开发者信息</div>
                <el-form label-width="210px" :model="formData">
                    <el-form-item v-model="formData.app_key" label="开发者ID(AppKey)">
                        <span class="dispose">{{ formData.app_key }}</span>
                        <el-button plain @click="onCopy(formData.app_key)">复制</el-button>
                        <div class="middle_box">
                            开发者ID是客易达scrm开发识别码，配合开发者密钥可调用客容达scrm接口能力。
                        </div>
                    </el-form-item>
                    <el-form-item v-model="formData.app_secret" label-width="190px" label="开发者秘钥(AppSecret)">
                        <el-tooltip class="box-item" effect="light" placement="top">
                            <template #content>
                                为保障账号安全，公众平台不再储存<br />AppSecret；如果遗忘，请重置。</template
                            >
                            <img src="@/assets/icon/question.png" alt="" class="icon" />
                        </el-tooltip>
                        <span class="dispose">{{ formData.app_secret ? '已设置' : '未设置' }}</span>
                        <el-button plain @click="getSecret(formData.app_secret)">{{
                            formData.app_secret ? '重置' : '获取'
                        }}</el-button>
                        <div class="middle_box m_l">
                            开发者密钥是校验客易达开发者身份的密码，具有极高的安全性。切记勿把密钥直接交给第三方开发者或直接储存在代码中。
                        </div>
                    </el-form-item>
                    <el-form-item v-model="formData.white_ips" label="IP白名单">
                        <span class="dispose"> {{ formData.white_ips.length ? '已设置' : '未设置' }}</span>
                        <el-button plain @click="changeConfig">
                            {{ formData.white_ips.length ? '修改设置' : '配置' }}</el-button
                        >
                        <div class="middle_box">
                            通过开发者ID及密钥调用获取access_token接口时，需要设置访问来源IP为白名单。
                        </div>
                    </el-form-item>
                    <div class="spilt"></div>
                    <!-- 服务配置信息 -->
                    <div class="procedure_box">
                        <div class="title">
                            服务配置信息
                            <p><img :src="formData.state == 1 ? status_icon.stop : status_icon.stat" alt="" /></p>
                            <span :class="formData.state == 1 ? 'hint' : 'hint2'">{{
                                formData.state == 1 ? '未开启' : '已开启'
                            }}</span>
                        </div>
                        <div v-if="formData.state !== 1">
                            <el-button plain :disabled="isChange" @click="modification">修改配置</el-button>
                            <el-button plain @click="stop">停用</el-button>
                        </div>
                    </div>
                    <div v-if="formData.state == 1" class="content">
                        <img src="/static/basic/Group.png" />
                        <div class="content_tips">
                            <div class="open">您还没有开启开发者服务配置！</div>
                            <el-button type="primary" @click="opend">确认开启</el-button>
                        </div>
                    </div>
                    <!-- 服务配置信息 -->
                    <div v-if="formData.state == 2">
                        <el-form ref="configRef" :model="formData" :rules="rules">
                            <el-form-item label="令牌(Token)" prop="encrypt_token" label-width="230px">
                                <el-input
                                    v-model="formData.encrypt_token"
                                    :disabled="!isChange"
                                    maxlength="32"
                                    minlength="3"
                                    placeholder="必须为英文或数字，长度为3-32字符"
                                    class="service_width">
                                    <template #suffix>
                                        <img
                                            v-show="!isChange"
                                            class="look_icon"
                                            :src="
                                                passForm.show.old
                                                    ? '/static/basic/look_icon.png'
                                                    : '/static/basic/hidden_icon.png'
                                            "
                                            alt=""
                                            @click="lookData(1)" />
                                    </template>
                                </el-input>
                            </el-form-item>
                            <el-form-item label="消息加解密密钥(EncodingAES)" prop="encrypt_key" label-width="230px">
                                <el-input
                                    v-model="formData.encrypt_key"
                                    :disabled="!isChange"
                                    maxlength="43"
                                    placeholder="消息加密密钥由43位字符组成，可随机修改，字符范围为A-Z，a-z，0-9"
                                    class="service_width">
                                    <template #suffix>
                                        <img
                                            v-show="!isChange"
                                            class="look_icon"
                                            :src="
                                                passForm.show.new
                                                    ? '/static/basic/look_icon.png'
                                                    : '/static/basic/hidden_icon.png'
                                            "
                                            alt=""
                                            @click="lookData(2)" />
                                    </template>
                                </el-input>
                                <el-button plain :disabled="!isChange" @click="random">随机生成</el-button>
                            </el-form-item>
                            <el-form-item label="系统事件订阅URL" prop="notify_url" label-width="230px">
                                <el-input
                                    v-model="formData.notify_url"
                                    :disabled="!isChange"
                                    placeholder="必须以http或https://开头，分别支持80端口和443端口"
                                    class="service_width" />
                            </el-form-item>
                        </el-form>
                    </div>
                </el-form>

                <div v-show="isChange" class="btn_box">
                    <el-button plain @click="reset">重置</el-button>
                    <el-button type="primary" @click="saveConfig">保存配置</el-button>
                </div>
            </div>
        </el-scrollbar>
    </div>
    <!-- 重置弹框 -->
    <el-dialog
        v-model="secretVisible"
        custom-class="enterprise_modal"
        width="540px"
        :title="dialogConfig.title"
        draggable
        :before-close="btnCancel">
        <div class="account_content">
            <div class="send_box">
                <p>
                    <img src="/static/appmarket/tips.png" style="width: 24px; height: 24px; margin-right: 12px" />
                    <span>{{ dialogConfig.text1 }}</span>
                </p>
                <p class="send_msg">
                    向管理员（{{ info.mobile_des }}）发送短信验证消息：
                    <el-button v-show="sendAuthCode" @click="sendCode">发送验证码</el-button>
                    <span v-show="!sendAuthCode">{{ autoTime }}秒后重新获取</span>
                    <el-form ref="formRef" :model="codeData" :rules="rules2" label-width="" class="dynamic">
                        <el-form-item prop="verificationCode" label="验证码" class="f_item">
                            <el-input v-model="codeData.verificationCode" class="code_input" />
                        </el-form-item>
                        <el-form-item class="line_item v-if='dialogConfig.text2'">
                            <p class="hint">{{ dialogConfig.text2 }}</p>
                        </el-form-item>
                    </el-form>
                </p>
            </div>
        </div>
        <template #footer>
            <el-button @click="onCancel">取消</el-button>
            <el-button type="primary" @click="onSecret(dialogConfig.type)">确定</el-button>
        </template>
    </el-dialog>
    <!-- 白名单 -->
    <el-dialog
        v-model="secretVisible2"
        custom-class="enterprise_modal white_box"
        width="540px"
        title="设置白名单"
        draggable
        :before-close="btnCancel">
        <p class="title">在IP白名单内的IP地址作为来源，获取access_token接口才可调用成功。</p>
        <el-form ref="ruleFormRef" :model="ruleForm" :rules="rules3">
            <el-form-item style="margin-bottom: 0" prop="content">
                <el-input
                    v-model="ruleForm.content"
                    class="text_area"
                    type="textarea"
                    placeholder="多个IP地址用回车键隔开"
                    @blur="checkTextarea"></el-input>
            </el-form-item>
        </el-form>
        <p class="hint">最多设置20个IP地址，多个IP地址用回车键隔开</p>
        <template #footer>
            <el-button @click="onCancel2">取消</el-button>
            <el-button type="primary" @click="onSecret2">确定</el-button>
        </template>
    </el-dialog>
</template>
<script lang="ts" setup>
import { reactive, onMounted, computed, ref } from 'vue';
import useClipboard from 'vue-clipboard3';
import { ElForm, ElMessage } from 'element-plus';
import {
    getDevelopInfo,
    setSecret,
    getCode,
    getInfo,
    setWhite,
    save,
    stopConfig,
    open
} from '@/api/channelconfig/basicConfiguration';
import { validatorNote, validatorUrl } from '@/utils/validate';

import { commonLink } from '@/api/channel/authconfig';
import { valueToNode } from '@babel/types';
const { toClipboard } = useClipboard();
const service = ref(1);
const secretVisible = ref(false);
const secretVisible2 = ref(false);
const isChange = ref(false);
const sendAuthCode = ref(true); // 是否获取验证码
const autoTime = ref(-1); // 验证码倒计时
const info = ref();
const formRef = ref();
const ruleFormRef = ref();
const configRef = ref();
const resData = ref({});
const content = ref();
const scene = ref();
const codeData = reactive({
    verificationCode: ''
});
const dialogConfig = reactive({
    type: '',
    title: '',
    text1: '',
    text2: ''
});
const card = reactive({
    imageList: [
        {
            name: '申请接入',
            url: '/static/basic/iconone.webp'
        },
        {
            name: '开发者信息配置',
            url: '/static/basic/icontwo.webp'
        },
        {
            name: '获取开发者凭证',
            url: '/static/basic/iconthree.webp'
        },
        {
            name: '接口接入',
            url: '/static/basic/iconfour.webp'
        }
    ]
});
const status_icon = reactive({
    stat: '/static/basic/stat_icon.png',
    stop: '/static/basic/stop_icon.png'
});
// 复制语句
const onCopy = async (val: any) => {
    try {
        await toClipboard(val);
        ElMessage.success('复制成功');
    } catch (e) {
        ElMessage.error('复制失败');
    }
};
const formData = reactive({
    app_key: '', //开发者id
    app_secret: '', // 开发者密钥
    encrypt_key: '', //消息加密解密密钥
    encrypt_token: '', //令牌
    notify_url: '', //系统事件订阅URL
    state: 1, //服务开启状态 1：未开启 2：已开启
    white_ips: [] //ip白名单
});
const ruleForm = reactive({
    content: ''
});
// 查看配置服务信息的配置
const passForm = reactive({
    show: {
        old: false,
        new: false
    }
});
// 短信验证
const note = (rule: any, value: any, callback: any) => {
    if (value == '') callback(new Error('验证码不能为空!'));
    else if (validatorNote(value)) {
        callback(new Error('验证码格式错误!'));
    } else {
        callback();
    }
};
// https || http 校验
const http = (rule: any, value: any, callback: any) => {
    if (validatorUrl(value)) {
        callback(new Error('必须以http或https://开头'));
    } else {
        callback();
    }
};
// 校验规则
const rules = reactive({
    encrypt_token: [{ required: true, message: '必须为英文或数字，长度为3-32字符', min: 3, max: 32, trigger: 'blur' }],
    encrypt_key: [
        {
            required: true,
            message: '消息加密密钥由43位字符组成，可随机修改，字符范围为A-Z，a-z，0-9',
            min: 43,
            max: 43,
            trigger: 'blur'
        }
    ],
    notify_url: [{ validator: http, trigger: 'blur' }]
});
const rules2 = reactive({
    verificationCode: [{ validator: note, trigger: 'change' }]
});
const rules3 = reactive({
    content: [{ required: true, message: '请填写选项内容', trigger: 'blur' }]
});
const configRules = reactive({});
const getDevelop = async (type?: number) => {
    const res = await getDevelopInfo({});
    if (type == 1) {
        ruleForm.content = res.white_ips ? res.white_ips.toString().replace(/,/g, '\n') : '';
    } else {
        Object.assign(formData, res);
        formData.encrypt_token = res.encrypt_token ? '*******************' : '';
        formData.encrypt_key = res.encrypt_key ? '*******************' : '';
        resData.value = res;
    }
};
const infoData = () => {
    getInfo().then((res: any) => {
        info.value = res;
    });
};
const opend = () => {
    open().then((res: any) => {
        getDevelop();
    });
};
// 密钥弹窗
const getSecret = async (val: any) => {
    if (val) {
        scene.value = 'open_platform_set_secret';
        dialogConfig.type = '1';
        dialogConfig.title = '重置开发者密钥';
        dialogConfig.text1 = '保存服务配置，旧配置将会失效，将会影响开发者接口的联通，请谨慎操作！';
        dialogConfig.text2 = '确认重置后，新的密钥将以短信的形式发送给管理员，为安全起见，请查收后记录并删除短信！';
        secretVisible.value = true;
    } else {
        setSecret().then((res: any) => {
            ElMessage.success('获取成功');
            getDevelop();
        });
    }
};
// 修改白名单
const changeConfig = () => {
    secretVisible2.value = true;
    getDevelop(1);
};
// 检查是否输入标准  防止ssr
const checkTextarea = () => {
    // if (content.value) return
    let str = ruleForm.content;
    str = str.replace(/<script>/g, '');
    str = str.replace(/alert/g, '');
    content.value = str;
};
// 白名单数据格式转换
const getContentArr = (str: string) => {
    if (!str.trim().length) {
        return [];
    }
    let arr: any = [];
    str.split('\n').forEach(item => {
        if (item.length > 0) {
            arr.push(item);
        }
    });
    arr = Array.from(new Set(arr)); //去除重复的
    return arr;
};
// 计算短信验证码倒计时
const smsLockTimeStorage: any = computed({
    get: () => {
        const val = localStorage.getItem('__scrm_register_lock_time__') ?? 0;
        return val;
    },
    set: (value: any) => {
        localStorage.setItem('__scrm_register_lock_time__', value);
    }
});
// 验证码倒计时函数
const smsLockTick = (num: number) => {
    sendAuthCode.value = false;
    autoTime.value = num;
    const autoTimeTimer = setInterval(() => {
        autoTime.value--;
        smsLockTimeStorage.value = autoTime.value;
        if (autoTime.value <= 0) {
            sendAuthCode.value = true;
            autoTime.value = 0;
            smsLockTimeStorage.value = 0;
            clearInterval(autoTimeTimer);
        }
    }, 1000);
};
if (smsLockTimeStorage.value > 0) {
    autoTime.value = smsLockTimeStorage.value;
    smsLockTick(autoTime.value);
} else {
    autoTime.value = 0;
}
// 发送验证码
const sendCode = () => {
    const params = {
        mobile: info.value.mobile,
        sms_type: scene.value
    };
    getCode(params).then((data: any) => {
        smsLockTick(60);
    });
};
// 密钥弹框取消
const onCancel = () => {
    if (!formRef.value) return;
    formRef.value.resetFields();
    secretVisible.value = false;
};
// 确认按钮
const onSecret = (type: string) => {
    if (!formRef.value) return;
    formRef.value.validate(valid => {
        if (valid) {
            if (type == '1') {
                setSecret({ code: codeData.verificationCode }).then((res: any) => {
                    ElMessage.success('重置成功');
                    onCancel();
                });
            } else if (type == '2') {
                const params = {
                    notify_url: formData.notify_url,
                    encrypt_token: formData.encrypt_token,
                    encrypt_key: formData.encrypt_key,
                    code: codeData.verificationCode
                };
                save(params).then((data: any) => {
                    ElMessage.success('保存成功！');
                    onCancel();
                    isChange.value = false;
                    lookData(1);
                    lookData(2);
                    getDevelop();
                });
            } else if (type == '3') {
                stopConfig({ code: codeData.verificationCode }).then((data: any) => {
                    ElMessage.success('保存成功！');
                    isChange.value = false;
                    onCancel();
                    getDevelop();
                });
            }
        } else {
            return false;
        }
    });
};
// 白名单取消
const onCancel2 = () => {
    if (!ruleFormRef.value) return;
    ruleFormRef.value.resetFields();
    secretVisible2.value = false;
};
// 白名单确认
const onSecret2 = () => {
    if (!ruleFormRef.value) return;
    ruleFormRef.value.validate(valid => {
        if (valid) {
            const params = {
                white_ips: getContentArr(ruleForm.content)
            };
            setWhite(params).then((res: any) => {
                ElMessage.success('设置成功');
                getDevelop();
                onCancel2();
            });
        } else {
            return false;
        }
    });
};
const fn = (st: string, b?: boolean, look?: string) => {
    if (b) {
        formData[st] = resData.value[look];
    } else {
        formData[st] = resData.value[look] ? '*******************' : '';
    }
};
// 查看信息及隐藏信息
const lookData = (n: number) => {
    switch (n) {
        case 1:
            passForm.show.old = !passForm.show.old;
            fn('encrypt_token', passForm.show.old, 'encrypt_token');
            break;
        case 2:
            passForm.show.new = !passForm.show.new;
            fn('encrypt_key', passForm.show.new, 'encrypt_key');
            break;
    }
};
// 生成随机字符串
const randomRange = (min: number, max: number) => {
    let returnStr = '';
    const range = max ? Math.round(Math.random() * (max - min)) + min : min;
    const charStr = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
    for (let i = 0; i < range; i++) {
        const index = Math.round(Math.random() * (charStr.length - 1));
        returnStr += charStr.substring(index, index + 1);
    }
    return returnStr;
};
// 获取随机数
const random = () => {
    formData.encrypt_key = randomRange(43, 43);
};
// 外链
const outerChain = async () => {
    const res = await commonLink({ code: 'check_process_develop_doc' });
    window.open(res.url, '_blank');
};
// 修改配置信息
const modification = () => {
    passForm.show.old = false;
    passForm.show.new = false;
    lookData(1);
    lookData(2);

    isChange.value = true;
};
// 停用
const stop = () => {
    scene.value = 'open_platform_disable';
    dialogConfig.type = '3';
    dialogConfig.title = '服务配置停用';
    dialogConfig.text1 = '停用后，开发者接口的服务将会停止响应，请慎重考虑！';
    secretVisible.value = true;
};
// 重置
const reset = () => {
    if (!configRef.value) return;
    configRef.value.resetFields();
    formData.encrypt_token = '';
    formData.encrypt_key = '';
    formData.notify_url = '';
    secretVisible2.value = false;
};
// 保存配置信息
const saveConfig = () => {
    if (!configRef.value) return;
    configRef.value.validate(valid => {
        if (valid) {
            scene.value = 'open_platform_set_config';
            dialogConfig.type = '2';
            dialogConfig.title = '保存服务配置';
            dialogConfig.text1 = '保存服务配置，旧配置将会失效，将会影响开发者接口的联通，请谨慎操作！';
            dialogConfig.text2 = '确认重置后，新的密钥将以短信的形式发送给管理员，为安全起见，请查收后记录并删除短信！';
            secretVisible.value = true;
        } else {
            return false;
        }
    });
};
onMounted(() => {
    getDevelop();
    infoData();
});
</script>
<style lang="scss" scoped>
.content_box {
    padding: 24px;
}

.procedure_box {
    margin-bottom: 24px;
    padding-left: 16px;
    border-left: 4px solid #ff6b00;
    display: flex;
    align-items: center;
    justify-content: space-between;

    .title {
        display: flex;
        align-items: center;

        p {
            display: flex;
            align-items: center;
            margin-left: 8px;

            img {
                width: 16px;
                height: 16px;
            }
        }
    }

    .hint {
        color: #fe292b;
        font-size: 14px;
    }

    .hint2 {
        color: #60b900;
        font-size: 14px;
    }
}

.icon_box {
    display: flex;
    margin-left: 20px;

    .icon_onbu {
        position: relative;
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: center;
        padding-right: 200px;

        &:last-of-type {
            .steps {
                border: none;
            }
        }

        .steps-name {
            white-space: nowrap;
        }
    }

    .icon_img {
        width: 48px;
        height: 48px;
        margin-bottom: 12px;
    }

    .steps {
        position: absolute;

        // left: 53px;
        // top: 62px;
        margin: -25px 0 0 280px;
        width: 200px;
        padding: 0 6px;
        border-bottom: 1px dashed #ffc69e;

        // &:last-child {
        //   border: none;
        // }
    }
}

.tips {
    font-size: 14px;
    margin-top: 24px;
    margin-left: 20px;

    .tips_text {
        color: #ff6b00;
        cursor: pointer;
    }
}

.spilt {
    border-top: 1px solid #eaeaea;
    margin: 24px 0;
}

.middle_box {
    font-size: 14px;
    color: #969696;
}

.m_l {
    margin-left: 19px;
}

.dispose {
    margin-right: 12px;
}

.icon {
    margin: 0 12px 0 -10px;
    vertical-align: middle;
}

.content {
    margin-top: 117px;
    text-align: center;

    .content_tips {
        display: flex;
        flex-direction: column;
        justify-content: center;
        align-items: center;

        .open {
            margin-bottom: 23px;
        }
    }
}

.service_width {
    width: 500px;
    margin-right: 10px;

    .look_icon {
        width: 16px;
        height: 16px;
        margin-top: 12px;

        // line-height: 40px;
    }
}

.btn_box {
    text-align: center;
}

.account_content {
    display: flex;
    align-items: center;
    margin-bottom: 24px;

    .send_box {
        p:first-child {
            display: flex;
            align-items: center;
            margin-bottom: 30px;
        }

        .send_msg {
            margin-left: 37px;

            .dynamic {
                .f_item {
                    margin-top: 16px;
                }

                :deep(.line_item) {
                    line-height: 0;
                }

                .code_input {
                    max-width: 316px;
                }

                .hint {
                    font-size: 14px;
                    max-width: 470px;
                    font-weight: 400;
                    color: #ff6b00;
                    line-height: 18px;
                }
            }
        }
    }
}

.white_box {
    .title {
        font-size: 14px;
        font-family: PingFangSC-Regular, 'PingFang SC';
        font-weight: 400;
        color: #ff6b00;
        line-height: 14px;
    }

    .text_area {
        margin: 16px 0 0;
    }

    .hint {
        font-size: 12px;
        font-family: PingFangSC-Regular, 'PingFang SC';
        font-weight: 400;
        color: #969696;
        line-height: 12px;
        margin-top: 16px;
    }
}
</style>
